Java JavaScript Python C# C C++ Go Kotlin PHP Swift R Ruby TypeScript Scala SQL Perl rust VisualBasic Matlab Julia

Inheritance → Python Inheritance

Inheritance

Python Inheritance

Inheritance in Python

Inheritance is a fundamental concept in Object-Oriented Programming (OOP) that promotes code reusability and establishes a hierarchical relationship between classes. It allows you to create new classes (child classes or subclasses) that inherit attributes and methods from existing classes (parent classes or superclasses). This avoids redundant code and helps maintain a structured, organized codebase. Python supports multiple inheritance, meaning a class can inherit from multiple parent classes.

Basic Inheritance

Let's start with a simple example. Suppose we have a `Dog` class:
Python Basic class example class Dog: def __init__(self, name, breed): self.name = name self.breed = breed def bark(self): print("Woof!") def describe(self): print(f"My name is {self.name} and I'm a {self.breed}.") my_dog = Dog("Buddy", "Golden Retriever") my_dog.bark() my_dog.describe()

Output

Woof! My name is Buddy and I'm a Golden Retriever.

Now, let's create a `GoldenRetriever` class that inherits from `Dog`:
Python Basic Inheritance example class Dog: def __init__(self, name, breed): self.name = name self.breed = breed def bark(self): print("Woof!") def describe(self): print(f"My name is {self.name} and I'm a {self.breed}.") my_dog = Dog("Buddy", "Golden Retriever") my_dog.bark() my_dog.describe() class GoldenRetriever(Dog): def __init__(self, name): super().__init__(name, "Golden Retriever") # Call parent class constructor self.is_friendly = True def fetch(self): print("Fetching the ball!") my_golden = GoldenRetriever("Max") my_golden.bark() # Inherits bark() from Dog my_golden.describe() # Inherits describe() from Dog, breed is automatically set my_golden.fetch()

Output

Woof! My name is Buddy and I'm a Golden Retriever. Woof! My name is Max and I'm a Golden Retriever. Fetching the ball!
`GoldenRetriever` inherits `bark()` and `describe()` from `Dog`. We use `super().__init__(name, "Golden Retriever")` to call the constructor of the parent class (`Dog`), initializing the `name` and `breed` attributes. We add a new attribute (`is_friendly`) and a new method (`fetch()`).

Method Overriding

A child class can override (redefine) methods from its parent class:
Python Method Overriding simple example class Animal: def speak(self): print("Generic animal sound") class Cat(Animal): def speak(self): print("Meow!") my_animal = Animal() my_animal.speak() my_cat = Cat() my_cat.speak()

Output

Generic animal sound Meow!
The `Cat` class overrides the `speak()` method from the `Animal` class.

Multiple Inheritance

Python supports inheriting from multiple parent classes:
Python Multiple Inheritance basic example class Flyer: def fly(self): print("Flying!") class Swimmer: def swim(self): print("Swimming!") class FlyingFish(Flyer, Swimmer): # Inherits from Flyer and Swimmer pass my_fish = FlyingFish() my_fish.fly() my_fish.swim()

Output

Flying! Swimming!
`FlyingFish` inherits `fly()` from `Flyer` and `swim()` from `Swimmer`.

Method Resolution Order (MRO)

When a method is called on a class that inherits from multiple parents, Python uses a specific order to determine which method to execute. This is the Method Resolution Order (MRO), determined using the C3 linearization algorithm. You can check the MRO using `__mro__` or `mro()`:
Method Resolution Order (MRO) print(FlyingFish.__mro__) print(FlyingFish.mro())

Output

(<class '__main__.FlyingFish'>, <class '__main__.Flyer'>, <class '__main__.Swimmer'>, <class 'object'>) [<class '__main__.FlyingFish'>, <class '__main__.Flyer'>, <class '__main__.Swimmer'>, <class 'object'>]

Diamond Problem

Multiple inheritance can lead to the "diamond problem" if two parent classes share a common ancestor and have conflicting methods. Python's MRO helps to avoid ambiguities in most cases, but careful design is essential to prevent unexpected behavior.

Polymorphism

Inheritance enables polymorphism – the ability to treat objects of different classes uniformly.
Inheritance and polymorphism relationship example class Animal: # Parent class def __init__(self, name, sound): self.name = name self.sound = sound def speak(self): print(f"{self.name} says {self.sound}") class Dog(Animal): # Child class inheriting from Animal def __init__(self, name, breed): super().__init__(name, "Woof") # Call parent class constructor self.breed = breed def fetch(self): print(f"{self.name} fetches the ball!") class Bird(Animal): def __init__(self, name, sound): super().__init__(name, sound) def speak(self): # Overrides the speak() method from Animal print(f"{self.name} chirps {self.sound}") my_bird = Bird("Tweety", "Chirp") my_bird.speak() # Calls Bird's version of speak() my_dog = Dog("Buddy", "Golden Retriever") my_dog.speak() # Inherits speak() from Animal my_dog.fetch() # Dog's own method print(my_dog.name, my_dog.breed) # Accessing attributes from both parent and child animals = [Dog("Max", "Labrador"), Bird("Polly", "Tweet"), Animal("Generic", "Generic Sound")] class Flyer: def fly(self): print("I can fly!") class Swimmer: def swim(self): print("I can swim!") class Duck(Flyer, Swimmer): # Inherits from both Flyer and Swimmer def quack(self): print("Quack!") my_duck = Duck() my_duck.quack() for animal in animals: animal.speak() # Each animal's speak() method is called appropriately

Output

Tweety chirps Chirp Buddy says Woof Buddy fetches the ball! Buddy Golden Retriever Quack! Max says Woof Polly chirps Tweet Generic says Generic Sound
⮚ `Animal` is the parent class defining common attributes (name, sound) and methods (speak) for animals. ⮚ `Dog` is the child class inheriting from `Animal`. It adds its own specific attributes (breed) and methods (fetch). ⮚ `super().__init__(name, "Woof")` calls the constructor of the parent class to initialize inherited attributes. This is crucial to properly initialize the parent class's state. ⮚ Even though `Dog`, `Bird`, and `Animal` have different `speak()` implementations, we can call `speak()` on each object without knowing its specific type.

Abstract Base Classes (ABCs)

ABCs define a common interface for subclasses, ensuring that they implement specific methods. This is useful for enforcing a contract between classes.
Abstract Base Classes from abc import ABC, abstractmethod class Shape(ABC): # Abstract Base Class @abstractmethod def area(self): pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14159 * self.radius**2 class Square(Shape): def __init__(self, side): self.side = side def area(self): return self.side**2 my_circle = Circle(5) my_square = Square(4) print(my_circle.area()) print(my_square.area()) # my_shape = Shape() # This will raise an error because Shape is abstract

Output

78.53975 16
`Shape` is an abstract class because it has an abstract method `area()`. Subclasses *must* implement `area()`. Attempting to instantiate `Shape` directly will raise an error.
In summary, inheritance is a powerful tool for creating reusable and maintainable code in Python. By understanding its mechanisms, including method overriding and the MRO, you can effectively leverage this OOP principle to build complex and well-structured applications. Remember to carefully consider the design of your class hierarchy to avoid potential pitfalls like the diamond problem.

Tutorials